import { createReadStream } from 'fs';
import { access, readFile } from 'fs/promises';
import { ServerResponse } from 'http';
import { extname, join, resolve } from 'path';

enum MIMEType {
	'.html' = 'text/html',
	'.js' = 'text/javascript',
	'.css' = 'text/css',
	'.json' = 'application/json',
	'.png' = 'image/png',
	'.jpg' = 'image/jpg',
	'.jpeg' = 'image/jpg',
	'.gif' = 'image/gif',
	'.svg' = 'application/image/svg+xml',
	'.wav' = 'audio/wav',
	'.mp4' = 'viceo/mp4',
	'.woff' = 'application/font-woff',
	'.ttf' = 'application/font-ttf',
	'.otf' = 'application/font-otf',
	'.eot' = 'application/vnd.ms-fontobejct',
	'.zip' = 'application/zip',
}

export const staticSource = (res: ServerResponse, dirPath: string, filePath: string) => {
	const sourcePath = resolve(join(dirPath, filePath));
	const ext = extname(sourcePath);

	access(sourcePath)
		.then(() => {
			if (filePath === '/') {
				throw Error('index path.');
			}
			// @ts-ignore
			const contentType = MIMEType[ext] || 'application/octet-stream';
			res.writeHead(200, { 'Content-Type': contentType });
			createReadStream(sourcePath).pipe(res);
		})
		.catch(() => {
			if (ext) {
				res.writeHead(404, { 'Content-Type': MIMEType['.html'] });
				res.end('404 - Not Found');
				return;
			}

			const indexPath = resolve(join(dirPath, '/index.html'));

			access(indexPath)
				.then(() => {
					res.writeHead(200, { 'Content-Type': MIMEType['.html'] });
					createReadStream(indexPath).pipe(res);
				})
				.catch(() => {
					res.writeHead(404, { 'Content-Type': MIMEType['.html'] });
					res.end('404 - Not Found');
				});
		});
};

export const localProxy = (res: ServerResponse, filePath: string) => {
	readFile(filePath)
		.then((data) => {
			const ext = extname(filePath);
			// @ts-ignore
			const contentType = MIMEType[ext] || 'application/octet-stream';
			res.writeHead(200, { 'Content-Type': contentType });
			res.end(data);
		})
		.catch(() => {
			res.writeHead(404, { 'Content-Type': MIMEType['.html'] });
			res.end('404 - Not Found');
		});
};
